package code

import "fmt"

// Type is an interface for value types
type Type interface {
	Coder
}

type Coder interface {
	Code() string
}

// SimpleType is a type that can be called directly
type SimpleType string

// Code returns token string in code format
func (t SimpleType) Code() string {
	return string(t)
}

func (t SimpleType) IsBuildIn() bool {
	return t == "uint" || t == "uint8" || t == "uint16" || t == "uint32" || t == "uint64" ||
		t == "int" || t == "int8" || t == "int16" || t == "int32" || t == "int64" ||
		t == "float32" || t == "float64" || t == "string" || t == "error" || t == "bool" || t == "complex64" ||
		t == "complex128" || t == "uintptr" || t == "byte" || t == "rune"
}

// ExternalType is a type that is called to another package
type ExternalType struct {
	PackageAlias string
	Name         string
}

// Code returns token string in code format
func (t ExternalType) Code() string {
	return fmt.Sprintf("%s.%s", t.PackageAlias, t.Name)
}

// PointerType is a model of pointer
type PointerType struct {
	ContainedType Type
}

// Code returns token string in code format
func (t PointerType) Code() string {
	return fmt.Sprintf("*%s", t.ContainedType.Code())
}

// ArrayType is a model of array
type ArrayType struct {
	ContainedType Type
}

// Code returns token string in code format
func (t ArrayType) Code() string {
	return fmt.Sprintf("[]%s", t.ContainedType.Code())
}

// MapType is a model of map
type MapType struct {
	KeyType   Type
	ValueType Type
}

// Code returns token string in code format
func (t MapType) Code() string {
	return fmt.Sprintf("map[%s]%s", t.KeyType.Code(), t.ValueType.Code())
}
